/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package airportmap;

/**
 *
 * @author oleg
 */



public class MercatorToXY {
    final private static double PI_2 = Math.PI * 0.5;
    final private static double MAX_LAT = 89.5;

    final private static double R_MAJOR = 6378137.0;
    final private static double R_MINOR = 6356752.3142;
    final private static double ECCENT = Math.sqrt(1 - Math.pow(R_MINOR / R_MAJOR, 2));
    final private static double ECCNTH = ECCENT * 0.5;

    final private static double DEG_RAD = Math.PI/180;
    final private static double RAD_DEG = 180/Math.PI;

    public static double merc_x(double longitude)
    {
            return longitude * DEG_RAD * R_MAJOR;
    }

    public static double unmerc_x(double x)
    {
            return x * RAD_DEG / R_MAJOR;
    }

    /*
    public static double merc_y(double latitude)
    {
        if (latitude > MAX_LAT) latitude = MAX_LAT;
        if (latitude < -MAX_LAT) latitude = -MAX_LAT;

        double phi = latitude * DEG_RAD;
        double con = ECCENT * Math.sin(phi);
        con = Math.pow( (1.0 - con) / (1.0 + con), ECCNTH );

        return -R_MAJOR * Math.log( Math.tan(0.5 * (PI_2 - phi)) / con );
    }
     * 
     */

    public static double unmerc_y(double y)
    {
            double ts = Math.exp(-y / R_MAJOR);
            double phi = PI_2 - 2.0 * Math.atan(ts);

            int i = 0;
            double dPhi = 1;
            while( (dPhi >= 0 ? dPhi : -dPhi) > 0.000000001 && i++ < 15 )
            {
                    double con = ECCENT * Math.sin(phi);
                    dPhi = PI_2 - 2.0 * Math.atan (ts * Math.pow((1.0 - con) /
                    (1.0 + con), ECCNTH)) - phi;
                    phi += dPhi;
            }

            return phi * RAD_DEG;
    }

    public static double mercY(double lat) {
        if (lat > 89.5) {
            lat = 89.5;
        }
        if (lat < -89.5) {
            lat = -89.5;
        }
        double temp = R_MINOR / R_MAJOR;
        double es = 1.0 - (temp * temp);
        double eccent = Math.sqrt(es);
        double phi = Math.toRadians(lat);
        double sinphi = Math.sin(phi);
        double con = eccent * sinphi;
        double com = 0.5 * eccent;
        con = Math.pow(((1.0-con)/(1.0+con)), com);
        double ts = Math.tan(0.5 * ((Math.PI*0.5) - phi))/con;
        double y = 0 - R_MAJOR * Math.log(ts);
        return y;
    }

}







